# output.manifest

- **类型：** `string | boolean | ManifestObjectConfig`
- **默认值：** `false`

配置如何生成 manifest 文件。

- `true`: 生成一个名为 `manifest.json` 的文件。
- `false`: 不生成 manifest 文件。
- `string`: 生成一个指定名称或路径的 manifest 文件。
- `object`: 生成一个指定选项的 manifest 文件。

manifest 文件包含所有构建产物的信息、以及 [入口模块](/config/source/entry) 与构建产物间的映射关系。

## 基础示例

添加以下配置来开启：

```ts title="rsbuild.config.ts"
export default {
  output: {
    manifest: true,
  },
};
```

构建完成后，Rsbuild 会生成 `dist/manifest.json` 文件：

```json title="dist/manifest.json"
{
  "allFiles": [
    "/static/css/index.[hash].css",
    "/static/js/index.[hash].js",
    "/static/images/logo.[hash].png",
    "/index.html"
  ],
  "entries": {
    "index": {
      "initial": {
        "js": ["/static/js/index.[hash].js"],
        "css": ["/static/css/index.[hash].css"]
      },
      "assets": ["/static/images/logo.[hash].png"],
      "html": ["/index.html"]
    }
  }
}
```

## Manifest 结构

manifest 文件默认输出的结构为：

```ts
type FilePath = string;

type ManifestList = {
  entries: {
    /** key 为 entry 名称，对应 Rsbuild 的 source.entry 配置 */
    [entryName: string]: {
      initial?: {
        js?: FilePath[];
        css?: FilePath[];
      };
      async?: {
        js?: FilePath[];
        css?: FilePath[];
      };
      /** 当前 entry 关联的 HTML 页面 */
      html?: FilePath[];
      /** 和当前 entry 相关的其他资源（如 png、svg、source map 等） */
      assets?: FilePath[];
    };
  };
  /** 铺平的所有 assets */
  allFiles: FilePath[];
};
```

## 通过 hooks 访问

你可以通过 Rsbuild 的 [hooks](/plugins/dev/hooks) 访问生成的 manifest 数据。

例如：

```ts
api.onAfterBuild(({ environments }) => {
  console.log(environments.web.manifest);
});
```

> 参考 [Environment API - manifest](/api/javascript-api/environment-api#manifest) 了解更多。

## 选项

`output.manifest` 可以是一个对象，以下是所有可选项：

### filename

- **类型：** `string`
- **默认值：** `'manifest.json'`

指定 manifest 文件的名称或路径。

`filename` 可以是一个相对于 `dist` 目录的路径，比如输出为 `dist/static/my-manifest.json`：

```ts title="rsbuild.config.ts"
export default {
  output: {
    manifest: {
      filename: './static/my-manifest.json',
    },
  },
};
```

这可以简写为：

```ts title="rsbuild.config.ts"
export default {
  output: {
    manifest: './static/my-manifest.json',
  },
};
```

### generate

- **类型：**

```ts
type ManifestGenerate = (params: {
  files: FileDescriptor[];
  manifestData: ManifestData;
}) => Record<string, unknown>;
```

- **默认值：** `undefined`
- **版本：** `>= 1.2.0`

通过 `manifest.generate` 函数可以自定义 manifest 文件的内容。该函数接收以下参数：

- `files`: 所有输出的文件的描述信息。
- `manifestData`: 默认的 manifest 数据。

例如，仅保留 `allAssets` 字段：

```ts title="rsbuild.config.ts"
export default {
  output: {
    manifest: {
      generate: ({ manifestData }) => {
        return {
          allAssets: manifestData.allFiles,
        };
      },
    },
  },
};
```

你也可以基于 `files` 来自定义 manifest 文件的内容，`files` 的结构如下：

```ts
interface FileDescriptor {
  name: string;
  path: string;
  isAsset: boolean;
  isChunk: boolean;
  isInitial: boolean;
  isModuleAsset: boolean;
  chunk?: import('@rspack/core').Chunk;
}
```

下面是 `files` 的一个示例：

```ts
const files = [
  {
    name: 'index.js',
    path: '/static/js/index.[hash].js',
    isAsset: false,
    isChunk: true,
    isInitial: true,
    isModuleAsset: false,
    chunk: {
      // Chunk info...
    },
  },
  {
    name: 'index.html',
    path: '/index.html',
    isAsset: true,
    isChunk: false,
    isInitial: false,
    isModuleAsset: false,
  },
];
```

### filter

- **类型：**

```ts
type ManifestFilter = (file: FileDescriptor) => boolean;
```

- **默认值：** `file => !file.name.endsWith('.LICENSE.txt')`
- **版本：** `>= 1.2.0`

允许你过滤包含在 manifest 中的文件。该函数接收一个 `file` 参数，返回 `true` 表示保留该文件，返回 `false` 表示不保留该文件。

默认情况下，`*.LICENSE.txt` 文件不会被包含在 manifest 文件中，因为这些许可证文件仅用于声明开源协议，不会在运行时被使用。

例如，仅保留 `*.js` 文件：

```ts title="rsbuild.config.ts"
export default {
  output: {
    manifest: {
      filter: (file) => file.name.endsWith('.js'),
    },
  },
};
```

生成的 manifest 文件中仅会包含 `*.js` 文件：

```json title="dist/manifest.json"
{
  "allFiles": ["/static/js/index.[hash].js"],
  "entries": {
    "index": {
      "initial": {
        "js": ["/static/js/index.[hash].js"]
      }
    }
  }
}
```

或者是包含所有文件：

```ts title="rsbuild.config.ts"
export default {
  output: {
    manifest: {
      filter: () => true,
    },
  },
};
```

## 多个环境

在使用 [environments](/config/environments) 并配置多个环境时，请为每个环境指定独立的 `manifest.filename` 值，以防止不同环境生成的 manifest 文件相互覆盖。

例如，为 `web` 环境使用默认的 `manifest.json`，同时为 `node` 环境使用 `manifest-node.json`：

```ts title="rsbuild.config.ts"
export default {
  environments: {
    web: {
      output: {
        manifest: true,
      },
    },
    node: {
      output: {
        target: 'node',
        manifest: {
          filename: 'manifest-node.json',
        },
      },
    },
  },
};
```

你也可以选择性地仅为特定环境生成 manifest 文件：

```ts title="rsbuild.config.ts"
export default {
  environments: {
    web: {
      output: {
        manifest: true,
      },
    },
    node: {
      output: {
        target: 'node',
      },
    },
  },
};
```
